/**
 * 字典工具函数 - 带缓存和防重复请求
 */
import { getDictDataByCode } from '@/api/system/dict.api'

import { to } from './promise'

// 字典缓存对象
const dictCache: Record<string, DictData[]> = {}

// 正在进行的请求缓存，避免重复请求
const pendingRequests: Record<string, Promise<DictData[]>> = {}

/**
 * 获取字典数据，带缓存和防重复请求
 * @param dictCode 字典编码
 * @returns 字典数据数组
 */
export async function getDict(dictCode: string): Promise<DictData[]> {
  // 如果已有缓存，直接返回
  if (dictCache[dictCode]) {
    return Promise.resolve(dictCache[dictCode])
  }

  // 如果已有正在进行的请求，等待该请求完成
  if (dictCode in pendingRequests) {
    return pendingRequests[dictCode]
  }

  // 创建新的请求Promise
  const requestPromise = (async () => {
    const [error, response] = await to(getDictDataByCode({ dictCode }))

    if (error) {
      console.error(`获取字典 ${dictCode} 失败:`, error)
      return []
    }

    const data = response || []
    // 缓存数据
    dictCache[dictCode] = data
    return data
  })().finally(() => {
    // 请求完成后清理pending状态
    delete pendingRequests[dictCode]
  })

  // 将请求Promise存储到pendingRequests中
  pendingRequests[dictCode] = requestPromise

  return requestPromise
}

/**
 * 清除字典缓存
 * @param dictCode 字典编码，如果不传则清除所有缓存
 */
export function clearDictCache(dictCode?: string) {
  if (dictCode) {
    delete dictCache[dictCode]
    delete pendingRequests[dictCode]
  } else {
    // 清除所有缓存
    Object.keys(dictCache).forEach((key) => delete dictCache[key])
    Object.keys(pendingRequests).forEach((key) => delete pendingRequests[key])
  }
}

/**
 * 预加载字典数据
 * @param dictCodes 字典编码数组
 */
export async function preloadDicts(dictCodes: string[]) {
  const promises = dictCodes.map((code) => getDict(code))
  await Promise.all(promises)
}

/**
 * 根据字典值获取字典标签
 * @param dictCode 字典编码
 * @param dictValue 字典值
 * @returns 字典标签
 */
export async function getDictLabel(dictCode: string, dictValue: string | number): Promise<string> {
  const dictList = await getDict(dictCode)
  const item = dictList.find((d) => d.dictValue === String(dictValue))
  return item?.dictLabel || String(dictValue)
}

/**
 * 将字典数据转换为下拉选项格式
 * @param dictCode 字典编码
 * @returns 下拉选项数组 { label, value }
 */
export async function getDictOptions(
  dictCode: string
): Promise<Array<{ label: string; value: string }>> {
  const dictList = await getDict(dictCode)
  return dictList.map((item) => ({
    label: item.dictLabel,
    value: item.dictValue
  }))
}

/**
 * 将字典数据转换为Map对象，便于快速查找
 * @param dictCode 字典编码
 * @returns Map<dictValue, dictLabel>
 */
export async function getDictMap(dictCode: string): Promise<Map<string, string>> {
  const dictList = await getDict(dictCode)
  const map = new Map<string, string>()
  dictList.forEach((item) => {
    map.set(item.dictValue, item.dictLabel)
  })
  return map
}
